// import { setting } from "../../setting";
import { Engine } from "../../Engine";
import { must } from "../../core/logic";
import { Parameter } from "./Parameter";
class Buffer extends Parameter {
    /**
     * 
     * @param {*} opts 
     * @param {Number} opts.group
     * @param {Number} opts.binding 
     * @param {GPUBufferUsage} opts.usage GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST。
     * @param {GPUShaderStage} opts.visibility GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT|GPUShaderStage.COMPUTE
     * @param {String} opts.type "uniform"|"storage"|"read-only-storage"
     * @param {Number} opts.size ArrayBuffer的字节大小。
     * @param {ArrayBuffer} opts.data
     */
    constructor(opts = {}) {
        super(opts);
        //运行参数
        this.gpu = {
            buffer: null,
            layout: null,
            entry: null
        }
        //布局部分
        if (opts.buffer) {
            this.gpu.buffer = opts.buffer
            this.gpu.layout = {
                binding: this.binding,
                visibility: opts.visibility,
                buffer: {
                    type: opts.type
                },
            };
            this.gpu.entry = {
                binding: this.binding,
                resource: {
                    buffer: this.gpu.buffer,
                    size: this.gpu.buffer.size,
                }
            }
        } else {
            this._usage = must(opts.usage);
            this._visibility = must(opts.visibility);
            this._type = must(opts.type);
            this._size = must(opts.size);
            this.updateLayout();
            //数据部分
            if (opts.data) {
                this.buffer(opts.data);
            }
        }

    }
    set usage(v) {
        if (v == this._usage) {
            return;
        }
        this._usage = v;
        //销毁
        if (this.gpu.buffer) {
            this.gpu.buffer.destroy();
            this.gpu.buffer = null;
        }
        return this;
    }
    get usage() {
        return this._usage;
    }
    set visibility(v) {
        if (v == this._visibility) {
            return;
        }
        this._visibility = v;
        this.updateLayout();
        return this;
    }
    get visibility() {
        return this._visibility;
    }
    set type(v) {
        if (v == this._type) {
            return;
        }
        this._type = v;
        this.updateLayout();
        return this;
    }
    get type() {
        return this._type;
    }
    set size(v) {
        if (this._size == v) {
            return false;
        }
        this._size = v;
        //销毁
        if (this.gpu.buffer) {
            this.gpu.buffer.destroy();
            this.gpu.buffer = null;
        }
        this.gpu.entry = null;
        return this;
    }
    get size() {
        return this._size;
    }
    updateLayout() {
        this.gpu.layout = {
            binding: this.binding,
            visibility: this.visibility,
            buffer: {
                type: this.type
            },
        }
        return this;
    }
    buffer(data, offset = 0) {
        if (!data) {
            return;
        }
        if (!this.gpu.buffer) {
            this.gpu.buffer = Engine.instance.device.createBuffer({
                label: this.name,
                size: this.size,
                usage: this.usage
            });
        }
        Engine.instance.queue.writeBuffer(
            this.gpu.buffer,
            offset,
            data
        );
        if (!this.gpu.entry) {
            this.gpu.entry = {
                binding: this.binding,
                resource: {
                    buffer: this.gpu.buffer,
                    size: this.size,
                }
            }
        }
    }
    destroy() {
        if (this.watchers.length <= 0) {
            if (this.gpu && this.gpu.buffer) {
                // this.gpu.buffer.destroy();
                this.gpu.buffer = null;
                this.gpu = null;
            }
            return true;
        }
        return false;
    }
}
export { Buffer }